package samplegameplugin;

import gamefw.framework.Coordinate;
import gamefw.gameplugin.AbstractGameLogic;
import gamefw.gameplugin.AbstractPlayer;
import gamefw.gameplugin.GameBoard;
import gamefw.gameplugin.GameEntity;
import gamefw.gameplugin.PlayResult;

public class SampleGameLogic extends AbstractGameLogic {

	private AbstractPlayer winner = null;
	
	@Override
	public void initialize() {
		getGameManager().getInputManager().registerSpecialEventListener(this);
	}
	
	@Override
	public String getGameTitle() {
		return "Tic Tac Toe";
	}
	
	@Override
	public Coordinate getScreenSize() {
		return new Coordinate(300, 350);
	}

	@Override
	public int getPlayersNumber() {
		return 2;
	}

	@Override
	public AbstractPlayer getWinner() {
		return winner;
	}

	@Override
	public int getNextPlayerIndex() {
		if (getCurrentPlayerIndex() == -1) {
			return 0;
		} else {
			return (getCurrentPlayerIndex() + 1) % 2;
		}
	}

	private AbstractPlayer getOwner(int x, int y){
		GameBoard board = getBoard();
		GameEntity entity = board.getEntity(new Coordinate(x, y));
		return entity == null ? null : entity.getOwner();
	}
	
	@Override
	public boolean isGameOver() {
		GameBoard board = getBoard();

		// columns
		for (int i = 0; i < board.getColsCount(); i++) {
			for (int j = 0; j < board.getRowsCount(); j++) {
				if (winner == null) {
					winner = getOwner(i, j);
					if(winner == null)
						break;
				} else {
					if (winner != getOwner(i, j)) {
						winner = null;
						break;
					}
				}
			}
			if (winner != null) {
				return true;
			}
		}

		// rows
		for (int i = 0; i < board.getRowsCount(); i++) {
			for (int j = 0; j < board.getColsCount(); j++) {
				if (winner == null) {
					winner = getOwner(j, i);
					if(winner == null)
						break;
				} else {
					if (winner != getOwner(j, i)) {
						winner = null;
						break;
					}
				}
			}
			if (winner != null) {
				return true;
			}
		}

		// cross
		for (int i = 0; i < board.getRowsCount(); i++) {
			if (winner == null) {
				winner = getOwner(i, i);
				if(winner == null)
					break;
			} else {
				if (winner !=  getOwner(i, i)) {
					winner = null;
					break;
				}
			}
			
		}
		if (winner != null) {
			return true;
		}
		
		
		// back cross
		for (int i = 0; i < board.getRowsCount(); i++) {
			if (winner == null) {
				winner =  getOwner(i,board.getRowsCount() - i - 1);
				if(winner == null)
					break;
			} else {
				if (winner != getOwner(i,board.getRowsCount() - i - 1)) {
					winner = null;
					break;
				}
			}
			
		}
		if (winner != null) {
			return true;
		}
		
		boolean allPlaceToken = true;
		for(int i = 0; i < board.getColsCount(); i ++){
			for(int j = 0; j < board.getRowsCount(); j++){
				if(getOwner(i, j) == null){
					allPlaceToken = false;
					break;
				}
			}
		}
		// no winner
		return allPlaceToken;
	}

	@Override
	public String[] getInitialEntities() {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	protected void handlePlayResult(PlayResult result) {
		switch (result.getResultType()) {
		case SELECT:
			GameEntity entity = getGameManager().createEntity(
					Integer.toString(getCurrentPlayerIndex()));
			entity.setOwner(getPlayer(getCurrentPlayerIndex()));
			getBoard().setEntity(result.getPosition(), entity);
		}
	}

	@Override
	protected void preDisplay() {
		if (getGameManager().getResourceType().equals("txt")) {
			if (isGameOver()) {
				displayWinner();
			} else {
				displayTurn();
			}
		}
	}

	@Override
	protected void postDisplay() {
		if (getGameManager().getResourceType().equals("png")) {
			if (isGameOver()) {
				displayWinner();
			} else {
				// TODO: Display turn in a different way.
//				displayTurn();
			}
		}
	}

	private void displayTurn() {
		int currentPlayerIndex = getCurrentPlayerIndex();
		String message = "Player " + (currentPlayerIndex + 1) + "'s Turn!";
		
		getGameManager().getOutputManager().printString(message);
	}
	
	private void displayWinner() {
		AbstractPlayer player = getWinner();
		String message = null;
		if (player != null) {
			message = "Game Over!\nPlayer " + (player.getIndex() + 1) + " won!";
		} else {
			message = "Game Over!\nDraw!";
		}
		
		getGameManager().getOutputManager().printString(message);
	}

	@Override
	public void onQuit() {
		System.exit(0);
	}
}
